package ar.com.quickMart.supermarketwsclient.soap;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ar.com.quickMart.logic.SuperMarket;

public class SuperMarketWSSoapClient {
	
	String destination ;
	String uri;
	String namespace;

	public SuperMarketWSSoapClient(SuperMarket sup){
		super();
		
		destination = sup.getUrl() + "/SuperMarketWS/SuperMarketWS.asmx";
		uri = "http://RPMiniMarket.com.ar/quickMart";
		namespace = "";//"RPMiniMarketServer";
	}
	

	
	public boolean testWebService(){
		
		
		String operation ="HelloWorld";
		
		
		try{
			
			SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection connection = soapConnFactory.createConnection();

            // Creacion del message
            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage message = messageFactory.createMessage();

            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();

            // This method demonstrates how to set HTTP and SOAP headers.
            // setOptionalHeaders(message, envelope);
            
          //added the SOAPAction to the header
            message.getMimeHeaders().setHeader("SOAPAction", uri + "/" + operation); 

            // Create and populate the body
            SOAPBody body = envelope.getBody();

            // se agrega la llamada a la operacion en el body
            SOAPElement bodyElement = body.addChildElement(
                    envelope.createName(operation, namespace, uri));
            
            message.saveChanges();
            
            
            // Se envia el mensaje
            SOAPMessage reply = connection.call(message, destination);

            soapPart = reply.getSOAPPart();
            envelope = soapPart.getEnvelope();
            body = envelope.getBody();

        
            if(envelope.getTextContent().equals("Hello World")){
            	return true;
            }
            else{
            	return false;
            }
			
		}
		catch(Exception ex){
			
			ex.printStackTrace();
			
			return false;
		}

	}
	
	public Float getProductPrice(long barCode){
		
		String operation ="getProductPrice";
		
		try{
			
			SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection connection = soapConnFactory.createConnection();

            // Creacion del message
            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage message = messageFactory.createMessage();

            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            
            //added the SOAPAction to the header
            message.getMimeHeaders().setHeader("SOAPAction", uri + "/" + operation);   

            // Create and populate the body
            SOAPBody body = envelope.getBody();

            // se agrega la llamada a la operacion en el body
            SOAPElement bodyElement = body.addChildElement(
                    envelope.createName(operation, namespace, uri));
            
            SOAPElement barCodeAttr = bodyElement.addChildElement("barCode");
            barCodeAttr.setTextContent(Long.toString(barCode));
            
            message.saveChanges();
            
           
            //message.writeTo(System.out);
            
            // Se envia el mensaje
            SOAPMessage reply = connection.call(message, destination);

            soapPart = reply.getSOAPPart();
            envelope = soapPart.getEnvelope();
            body = envelope.getBody();

            //reply.writeTo(System.out);
            
            return Float.parseFloat(body.getTextContent());
			
		}
		catch(Exception ex){
			
			ex.printStackTrace();
			
			return null;
		}
		
	}
	
	public Map<Long,Float> getProductsPrice(List<Long> barcodes){
		String operation ="getProductsPrice";
		
		try{
			
			SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection connection = soapConnFactory.createConnection();

            // Creacion del message
            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage message = messageFactory.createMessage();

            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            
            //added the SOAPAction to the header
            message.getMimeHeaders().setHeader("SOAPAction", uri + "/" + operation);   

            // Create and populate the body
            SOAPBody body = envelope.getBody();

            // se agrega la llamada a la operacion en el body
            SOAPElement bodyElement = body.addChildElement(
                    envelope.createName(operation, namespace, uri));
            
            SOAPElement barCodesAttr = bodyElement.addChildElement("barCodes");
            
            for(Long barCode : barcodes){
            	SOAPElement longAttr = barCodesAttr.addChildElement("long");
            	longAttr.setTextContent(Long.toString(barCode));
            }
            
            
            message.saveChanges();
            
           
            //message.writeTo(System.out);
            
            // Se envia el mensaje
            SOAPMessage reply = connection.call(message, destination);

            
            
            soapPart = reply.getSOAPPart();
            envelope = soapPart.getEnvelope();
            body = envelope.getBody();

            //reply.writeTo(System.out);
            
            NodeList results = body.getChildNodes().item(0).getChildNodes().item(0).getChildNodes();
            
            if( results.getLength() == 0){//TODO: comprobar si devuelve una excepcion
            	return null;
            }
            else{
            	
            	Map<Long, Float> prices = new HashMap<Long,Float>();
            	for(int x=0; x < results.getLength(); x++){
                	
            		Node result = results.item(x);	
            		
                	prices.put(Long.parseLong(result.getFirstChild().getTextContent()),
                			Float.parseFloat(result.getLastChild().getTextContent()));
            		
                }
            	
            	return prices;
            }
            
            
           
			
		}
		catch(Exception ex){
			
			ex.printStackTrace();
			
			return null;
		}
	}

}
